using System;
using Config;
using Data;
using Map;
using MoonFramework.Scripts.Event;
using MoonFramework.Scripts.Mono;
using MoonFramework.Scripts.View.UI;
using MoonFramework.Template;
using MoonFramework.Test;
using Tool;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using InputManager = Tool.InputManager;

namespace UI.Bag
{
	public class UI_ItemSlot : MonoBehaviour
	{
		[SerializeField] private Image bgImage;
		[SerializeField] private Image iconImage;
		[SerializeField] private Text countText;
		
		public ItemData ItemData { get; private set; }	//格子里的数据
		public int Index { get; private set; }	//格子下标
		private UI_BagWindow ownerWindow;
		private Transform _iconTransform;
		private Transform _mTransform;

		private static UI_ItemSlot CurrentSelectSlot;
		public static UI_ItemSlot WeaponSlot;

		private Func<int, string> _onUseItem;
		
		private void Start()
		{
			_mTransform = transform;
			_iconTransform = iconImage.transform;
			// 交互事件
			this.OnMouseEnter(MouseEnter);
			this.OnMouseExit(MouseExit);
			this.OnBeginDrag(BeginDrag);
			this.OnDrag(Drag);
			this.OnEndDrag(EndDrag);
			this.BindMouseEffect();
		}

		private void OnEnable()
		{
			MonoManager.Instance.SendUpdateEvent(CheckMouseClick);
		}
		
		//进入对象池隐藏取消帧更新
		private void OnDisable()
		{
			MonoManager.Instance.RemoveUpdateEvent(CheckMouseClick);
		}

		#region 鼠标交互
		private bool _isMouseStay;

		/// <summary>
		/// 检测右键
		/// 是否可以使用物品检测
		/// </summary>
		private void CheckMouseClick()
		{
			if(ItemData == null || !_isMouseStay || _onUseItem == null) return;
			if (Input.GetMouseButtonDown(1))
			{
				ProjectTool.PlayAudio(_onUseItem(Index));
			}
		}
		
		private void EndDrag(PointerEventData eventData, object[] arg2)
		{
			// 确保有 ItemData
			if (ItemData == null) return;

			//格子与建筑物的交互
			if (InputManager.Instance.CheckSlotEndOnBuilding(ItemData.ConfigID))
			{
				ResetIcon();
				ProjectTool.PlayAudio(PlayerAudioName.Bag);
				ownerWindow.DiscardItem(Index);
				return;
			}
			
			// 如果没有选择格子，则重置光标状态
			if (!CurrentSelectSlot)
			{
				GameManger.Instance.SetCursorState(CursorState.Normal);
			}
			
			ResetIcon();
			// 如果当前格子和选择格子相同，则不做处理
			if (CurrentSelectSlot == this) return;

			// 物品丢弃
			if (!CurrentSelectSlot)
			{
				// 射线去检测有没有除了Mask以外的任何UI物体
				if (InputManager.Instance.CheckMouseOnUI()) return;
				//射线检测防止玩家将物品扔到大型物品上
				if(InputManager.Instance.CheckMouseOnBigMapObject()) return;
				if (InputManager.Instance.GetMouseWorldPositionOnGround(eventData.position, out var worldPos))
					DiscardItem(worldPos);
				return;
			}

			if (CurrentSelectSlot == WeaponSlot)
			{
				ProjectTool.PlayAudio(PlayerAudioName.Fail);
				UIManager.Instance.AddTips("请右键使用武器");
				return;
			}
			
			// 当前操作的是武器槽
			if (this == WeaponSlot)
			{
				HandleWeaponSlot();
			}
			// 当前是普通格子
			else
			{
				// 格子物品交换
				SwapSlotItem(this, CurrentSelectSlot);
				ProjectTool.PlayAudio(PlayerAudioName.Bag);
			}
		}

		private void ResetIcon()
		{
			// 图标归位
			_iconTransform.SetParent(_mTransform);
			_iconTransform.localPosition = Vector3.zero;
			_iconTransform.localScale = Vector3.one;
		}
		
		/// <summary>
		/// 处理武器格
		/// </summary>
		private void HandleWeaponSlot()
		{
			// 目标格子是空的，卸下武器的操作
			if (CurrentSelectSlot.ItemData == null)
			{
				ProjectTool.PlayAudio(PlayerAudioName.Fail);
				UIManager.Instance.AddTips("请右键卸下武器");
			}
			// 目标格子是武器
			else if (CurrentSelectSlot.ItemData.Config.ItemType == ItemType.Weapon)
			{
				ProjectTool.PlayAudio(PlayerAudioName.TakeUpWeapon);
				SwapSlotItem(this, CurrentSelectSlot);
			}
			// 目标格子不是武器
			else
			{
				ProjectTool.PlayAudio(PlayerAudioName.Fail);
				UIManager.Instance.AddTips("必须得是装备才行!");
			}
		}
		
		/// <summary>
		/// 丢弃物品
		/// </summary>
		private void DiscardItem(Vector3 worldPos)
		{
			//地面上产生丢弃物
			worldPos.y = 1;
			MapManager.Instance.CreateMapObject(ItemData.Config.MapObjectConfigID, worldPos);
			ProjectTool.PlayAudio(PlayerAudioName.Bag);
			ownerWindow.DiscardItem(Index);
		}

		/// <summary>
		/// 交换格子中物品数据
		/// </summary>
		public static void SwapSlotItem(UI_ItemSlot slot1, UI_ItemSlot slot2)
		{
			ItemData itemData1 = slot1.ItemData;
			ItemData itemData2 = slot2.ItemData;
			slot1.ownerWindow.SetItem(slot1.Index, itemData2);
			slot2.ownerWindow.SetItem(slot2.Index, itemData1);
		}

		private void Drag(PointerEventData arg1, object[] arg2)
		{
			if (ItemData == null) return;
			GameManger.Instance.SetCursorState(CursorState.Handle);
			_iconTransform.position = arg1.position;
		}

		//当前格子为选中状态，并且按下了右键，则目的是使用物品
		private void BeginDrag(PointerEventData arg1, object[] arg2)
		{
			if (ItemData == null) return;
			_iconTransform.SetParent(UIManager.Instance.DragLayer);
		}

		//鼠标离开
		private void MouseExit(PointerEventData arg1, object[] arg2)
		{
			if (CurrentSelectSlot) CurrentSelectSlot = null;
			GameManger.Instance.SetCursorState(CursorState.Normal);
			bgImage.sprite = ownerWindow.BgSprites[0];
			_isMouseStay = false;
		}

		//鼠标进入
		private void MouseEnter(PointerEventData arg1, object[] arg2)
		{
			CurrentSelectSlot = this;
			GameManger.Instance.SetCursorState(CursorState.Handle);
			bgImage.sprite = ownerWindow.BgSprites[1];
			_isMouseStay = true;
		}
		#endregion

		public void Init(int index, UI_BagWindow bagWindow, Func<int, string> onUseItem = null)
		{
			Index = index;
			ownerWindow = bagWindow;
			_onUseItem = onUseItem;
			bgImage.sprite = ownerWindow.BgSprites[0];
		}

		public void InitData(ItemData itemData)
		{
			this.ItemData = itemData;
			if (itemData == null)
			{
				// 外框设置为白色，隐藏数据，icon
				bgImage.color = Color.white;
				countText.gameObject.SetActive(false);
				iconImage.sprite = null;
				iconImage.gameObject.SetActive(false);
				return;
			}
			//有数据的情况
			countText.gameObject.SetActive(true);
			iconImage.gameObject.SetActive(true);
			iconImage.sprite = ItemData.Config.Icon;	//根据格子里面的配置来显示图片
			UpdateCountTextView();
		}

		public void UpdateCountTextView()
		{
			switch (ItemData.Config.ItemType)
			{
				case ItemType.Weapon:
					bgImage.color = Color.white;
					countText.text = (ItemData.ItemTypeData as ItemWeaponData)!.Durability + "%";
					break;
				case ItemType.Consumable:
					bgImage.color = new Color(0, 1, 0, 0.5f);
					countText.text = (ItemData.ItemTypeData as ItemConsumableItemData)?.Count.ToString();
					break;
				case ItemType.Material:
					bgImage.color = Color.white;
					countText.text = (ItemData.ItemTypeData as ItemMaterialItemData)?.Count.ToString();
					break;
				default:
					throw new ArgumentOutOfRangeException();
			}
		}
	}
}
